#include "page.h"
#include "urlaction.h"
#include <KAction>
#include <KActionCollection>
#include <KStandardAction>
#include <kurl.h>
#include <kio/netaccess.h>
#include <kmimetypetrader.h>
#include <QGridLayout>
#include <QList>
#include <kparts/browserextension.h>
#include <QPixmap>
#include <kfileitem.h>
#include <kactioncollection.h>
#include <kservicetypetrader.h>
#include <kmenu.h>

Page::Page( const KUrl& url, const KParts::OpenUrlArguments& arguments, const KParts::BrowserArguments& browserArguments, QWidget* parent ) : QWidget( parent )
{
    part = false;
    goTo( url, arguments, browserArguments );
}

// Page::partFactory: creates a new KPart for the Page.
KParts::ReadOnlyPart* Page::partFactory( const KUrl& url, const KParts::OpenUrlArguments&arguments )
{
    // Let's get the mimetype...
    pmimetype = KIO::NetAccess::mimetype( url, 0 );
    // ... and create the new one based on it
    KParts::ReadOnlyPart* part = KMimeTypeTrader::createPartInstanceFromQuery<KParts::ReadOnlyPart>( pmimetype, this, this );
    // now we open the page.
    part->setArguments( arguments );
    part->openUrl( url );
    // Connect the KPart to the various facilities we provide
    connect( part, SIGNAL( setWindowCaption( const QString & ) ), this, SLOT( setTitle( const QString & ) ) );
    connect(part, SIGNAL(setStatusBarText(const QString &)), this, SLOT(setStatus(const QString &)));
    connect( part, SIGNAL( completed() ), this, SLOT( doneLoading() ) );
    connect( part, SIGNAL( started( KIO::Job* ) ), this, SLOT( startLoading( KIO::Job* ) ) );
    KParts::BrowserExtension *ext = KParts::BrowserExtension::childObject(part);
    if (ext) {
        connect( ext, SIGNAL( openUrlRequest( const KUrl &, const KParts::OpenUrlArguments, KParts::BrowserArguments ) ), this, SLOT( goTo( const KUrl &, const KParts::OpenUrlArguments, KParts::BrowserArguments ) ) );
        connect( ext, SIGNAL( createNewWindow( const KUrl &, const KParts::OpenUrlArguments, KParts::BrowserArguments ) ), this, SIGNAL( newTab( const KUrl &, const KParts::OpenUrlArguments, KParts::BrowserArguments ) ) );
        connect( ext, SIGNAL( setLocationBarUrl( const QString & ) ), this, SLOT( setLocation( const QString & ) ) );
        connect( ext, SIGNAL( infoMessage( const QString & ) ), this, SLOT( setStatus( const QString & ) ) );
        connect( ext, SIGNAL( loadingProgress( int ) ), this, SIGNAL( newProgress( int ) ) );
        connect( ext, SIGNAL( popupMenu( QPoint,KUrl,mode_t,KParts::OpenUrlArguments,KParts::BrowserArguments,KParts::BrowserExtension::PopupFlags,KParts::BrowserExtension::ActionGroupMap ) ), this, SLOT( popupMenu( QPoint,KUrl,mode_t,KParts::OpenUrlArguments,KParts::BrowserArguments,KParts::BrowserExtension::PopupFlags,KParts::BrowserExtension::ActionGroupMap ) ) );
       connect( ext, SIGNAL( popupMenu( QPoint,KFileItemList,KParts::OpenUrlArguments,KParts::BrowserArguments,KParts::BrowserExtension::PopupFlags,KParts::BrowserExtension::ActionGroupMap ) ), this, SLOT( popupMenu( QPoint,KFileItemList,KParts::OpenUrlArguments,KParts::BrowserArguments,KParts::BrowserExtension::PopupFlags,KParts::BrowserExtension::ActionGroupMap ) ) );
    }

    return part;
}

void Page::setTitle( const QString& snewTitle )
{
    if ( ptitle != snewTitle ) {
        ptitle = snewTitle;
        emit newTitle( snewTitle );
    }
}

void Page::setStatus( const QString& snewStatus )
{
    if ( pstatus != snewStatus ) {
        pstatus = snewStatus;
        emit newStatus( snewStatus );
    }
}

void Page::setLocation( const QString& snewLocation )
{
    if ( purl.url() != snewLocation ) {
       purl = KUrl( snewLocation );
       emit newLocation( snewLocation );
       emit newUrl( purl );
    }
}

void Page::setUrl( const KUrl& unewUrl )
{
    if ( purl != unewUrl ) {
        purl = unewUrl;
        emit newLocation( purl.url() );
        emit newUrl( purl );
    }
}

void Page::goTo( const KUrl& uri, const KParts::OpenUrlArguments&arguments, const KParts::BrowserArguments& browserArguments )
{
    QString location = uri.url();
    KUrl url;
    if ( location.indexOf( ":" ) == -1 ) {
        url = KUrl( location.prepend( "http://" ) );
        setUrl( url );
    } else {
        url = uri;
    }
    if ( part ) {
        QString newMimetype = KIO::NetAccess::mimetype( url, 0 );
        if ( newMimetype == pmimetype ) {
            setUrl( url );
            part->setArguments( arguments );
            part->openUrl( url );
            phistory.append( url );
            return;
        }
        part->deleteLater();
        part->widget()->deleteLater();
    }
    part = partFactory( url, arguments );
    part->setParent( this );
    QGridLayout* gridLayout = new QGridLayout();
    if ( layout() ) delete layout();
    gridLayout->addWidget( part->widget() );
    setLayout( gridLayout );
    phistory.append( url );
    setUrl( url );
}

void Page::back()
{
    if ( phistory.size() != 1 and !phistory.isEmpty() ) {
        pfuture.prepend( phistory.last() );
        phistory.removeLast();
        goTo(phistory.last());
        phistory.removeLast();
    }
}

void Page::forward()
{
    if ( !pfuture.isEmpty() ) {
        phistory.append( pfuture.first() );
        pfuture.removeFirst();
        goTo(phistory.last());
        phistory.removeLast();
    }
}

void Page::reload()
{
    KParts::OpenUrlArguments args;
    args.setReload( true );
    goTo( phistory.last(), args );
    args.setReload( false );
}

void Page::popupMenu( const QPoint &global, const KUrl &url, mode_t mode, const KParts::OpenUrlArguments &args, const KParts::BrowserArguments& browserArgs, KParts::BrowserExtension::PopupFlags flags, const KParts::BrowserExtension::ActionGroupMap& actionGroups )
{
    KFileItem item( url, args.mimeType(), mode );
    KFileItemList items;
    items.append(  item );
    popupMenu(  global, items, args, browserArgs, flags, actionGroups );
}
void Page::popupMenu( const QPoint &global, const KFileItemList &items, const KParts::OpenUrlArguments &args, const KParts::BrowserArguments& browserArgs, KParts::BrowserExtension::PopupFlags itemFlags, const KParts::BrowserExtension::ActionGroupMap& _actionGroups )
{
    KActionCollection* popupActions = new KActionCollection( ( QWidget* )0 );
    KMenu* menu = new KMenu( this );
    if ( items.count() > 0 ) {
        UrlAction* newWinAction = new UrlAction( "window-new", popupActions, items.first().url(), args, browserArgs );
        newWinAction->setIcon( KIcon( "window-new" ) );
        newWinAction->setText( i18n( "Open in new window" ) );
        connect( newWinAction, SIGNAL( triggered( const KUrl &, const KParts::OpenUrlArguments, KParts::BrowserArguments ) ), this, SIGNAL( newWindow( const KUrl & ) ) );
        menu->addAction( newWinAction );

        UrlAction* newTabAction = new UrlAction( "window-new", popupActions, items.first().url() );
        newTabAction->setIcon( KIcon( "tab-new" ) );
        newTabAction->setText( i18n( "Open in new tab" ) );
        connect( newTabAction, SIGNAL( triggered( const KUrl, const KParts::OpenUrlArguments, KParts::BrowserArguments ) ), this, SIGNAL( newTab(  const KUrl &, const KParts::OpenUrlArguments, KParts::BrowserArguments ) ) );
        menu->addAction( newTabAction );
    }
    menu->addSeparator();
    menu->addAction( KStandardAction::back( this, SLOT( back() ), popupActions ) );
    KAction* reloadAction = KStandardAction::redisplay( this, SLOT( reload() ), popupActions );
    reloadAction->setText( i18n( "Reload" ) );
    menu->addAction( reloadAction );
    menu->addAction( KStandardAction::forward( this, SLOT( forward() ), popupActions ) );
    menu->popup( global );
}

